package model

import (
	"fmt"
	"gpt-api/framework/db"

	"github.com/spf13/viper"
)

type Score struct {
	db.BaseModel
	UserId       uint   `json:"user_id" gorm:"column:user_id;type:int;default:0;comment:用户ID"`
	Score        int    `json:"score" gorm:"column:score;type:int;default:0;comment:积分,正数增加,负数减少"`
	ScoreType    int    `json:"score_type" gorm:"column:score_type;type:int;default:0;comment:积分类型,0:充值获得,1:图片增强消耗,2:图片上色消费,3:图片生成视频消费,4:邀请用户获得,5:注册赠送,6:系统赠送,7.兑换码兑换"`
	Comment      string `json:"memory" gorm:"column:memory;type:varchar(255);default:'';comment:积分变动说明"`
	InviteUserId int64  `json:"invite_user_id" gorm:"column:invite_user_id;type:int;default:0;comment:被邀请用户ID"`
	// 关联被邀请用户
	InviteUser Users `json:"user" gorm:"foreignKey:ID;references:InviteUserId"`
}

func (Score) TableName() string {
	return "score"
}

func (s *Score) Create(database *db.DB) error {
	return database.Create(s).Error
}

/**
* 注意；积分充值成功后要修改users表中的积分字段
* @Description: 邀请用户积分变动
* @param inviterUserId 邀请用户ID
* @param inviteUserId 被邀请用户ID
* @param score 积分
* @return error
 */
func (s *Score) Charge(database *db.DB, inviterUserId int, inviteUserId uint64, score int) error {
	// 开启事务
	tx := database.Begin()

	// 查询邀请人信息
	var user Users
	errUser := tx.Model(user).Where("id = ?", inviterUserId).First(&user).Error
	if errUser != nil {
		return errUser
	}

	// 更新邀请人积分
	oldScore := user.Score
	user.Score += score
	errUserScore := tx.Model(&user).Where("id = ?", inviterUserId).Where("score = ?", oldScore).Updates(&user).Error
	if errUserScore != nil {
		tx.Rollback() // 事务回滚
		return errUserScore
	}

	// 生成邀请人积分变动记录
	s.UserId = uint(inviterUserId)
	s.Score = score
	s.Comment = fmt.Sprintf("%s,获得%d积分", "邀请用户赠送", score)
	s.ScoreType = 4
	s.InviteUserId = int64(inviteUserId)
	errScore := tx.Model(&s).Create(&s).Error
	if errScore != nil {
		tx.Rollback() // 事务回滚
		return errScore
	}

	// 提交事务
	tx.Commit()
	return nil
}

// 根据用户ID分页查询邀请积分记录
func (s *Score) GetInviteScoreByUserId(database *db.DB, userId uint64, page, size int) ([]Score, error) {
	var score []Score
	if page <= 0 {
		page = 1
	}
	if size <= 0 {
		size = 10
	}
	err := database.Model(s).Where("user_id = ? AND score_type = ?", userId, 4).Order("id desc").Preload("InviteUser").Offset((page - 1) * size).Limit(size).Find(&score).Error
	return score, err
}

/**
 *
 * @Description: 图片生成视频消费
 * @param userId
 * @return error
 */
func (s *Score) ColorfulTake(database *db.DB, userId uint) error {
	// 开启事务
	tx := database.Begin()

	// 记录消费积分
	score := viper.GetInt("score.colorfulTake")
	s.UserId = userId
	s.Score = score
	s.Comment = "图片上色消费" + viper.GetString("score.colorfulTake") + "积分"
	s.ScoreType = 2
	errScore := tx.Model(&s).Create(&s).Error
	if errScore != nil {
		tx.Rollback() // 事务回滚
		return errScore
	}

	// 更新用户积分
	var user Users
	errUser := tx.Model(&user).Where("id = ?", userId).First(&user).Error
	if errUser != nil {
		tx.Rollback() // 事务回滚
		return errUser
	}
	oldScore := user.Score
	user.Score -= score
	errUserScore := tx.Model(&user).Where("id = ?", userId).Where("score = ?", oldScore).Updates(&user).Error
	if errUserScore != nil {
		tx.Rollback() // 事务回滚
		return errUserScore
	}

	// 提交事务
	tx.Commit()
	return nil
}

/**
 *
 * @Description: 图片增强消费
 * @param userId
 * @return error
 */
func (s *Score) EnhanceTake(database *db.DB, userId uint) error {
	// 开启事务
	tx := database.Begin()

	score := viper.GetInt("score.enhanceTake")
	s.UserId = userId
	s.Score = score
	s.Comment = "图片增强消费" + viper.GetString("score.enhanceTake") + "积分"
	s.ScoreType = 1
	errScore := tx.Model(&s).Create(&s).Error
	if errScore != nil {
		tx.Rollback() // 事务回滚
		return errScore
	}

	// 更新用户积分
	var user Users
	errUser := tx.Model(&user).Where("id = ?", userId).First(&user).Error
	if errUser != nil {
		tx.Rollback() // 事务回滚
		return errUser
	}
	oldScore := user.Score
	user.Score -= score
	errUserScore := tx.Model(&user).Where("id = ?", userId).Where("score = ?", oldScore).Updates(&user).Error
	if errUserScore != nil {
		tx.Rollback() // 事务回滚
		return errUserScore
	}

	// 提交事务
	tx.Commit()
	return nil

}

/**
 *
 * @Description: 图片生成视频消费
 * @param userId
 * @return error
 */
func (s *Score) VideoTake(database *db.DB, userId uint) error {
	// 开启事务
	tx := database.Begin()

	score := viper.GetInt("score.videoTake")
	s.UserId = userId
	s.Score = score
	s.Comment = "图片生成视频消费" + viper.GetString("score.videoTake") + "积分"
	s.ScoreType = 3
	errScore := tx.Model(&s).Create(&s).Error
	if errScore != nil {
		tx.Rollback()
		return errScore
	}

	// 更新用户积分
	var user Users
	errUser := tx.Model(&user).Where("id = ?", userId).First(&user).Error
	if errUser != nil {
		tx.Rollback()
		return errUser
	}
	oldScore := user.Score
	user.Score -= score
	errUserScore := tx.Model(&user).Where("id = ?", userId).Where("score = ?", oldScore).Updates(&user).Error
	if errUserScore != nil {
		tx.Rollback()
		return errUserScore
	}

	// 提交事务
	tx.Commit()
	return nil
}

/**
 *
 * @Description: 获取用户的积分历史记录
 * @param userId
 * @param scoreType 积分类型,小于0查询全部
 * @return []Score
 * @return error
 */
func (s *Score) GetScoreHistory(database *db.DB, userId int, scoreType int) ([]Score, error) {
	var score []Score
	initQuery := database.Where("user_id = ?", userId)
	if scoreType >= 0 {
		initQuery = initQuery.Where("score_type = ?", scoreType)
	}
	err := initQuery.Find(&score).Error
	return score, err
}
